local LogMgr = class("LogMgr");
local MAX_COUNT = 50
-- DEBUG:用来debug的信息
-- NOTICE:框架底层的消息
-- WARN:警告
-- ERROR:错误
-- FATAL:致命性错误
-- FUNC:打印函数名称
-- DUMP：dump()

local LOG_LEVEL = {DEBUG = true, NOTICE = true ,WARN = true, ERROR = true, FATAL = true, FUNC = false, DUMP = true};
function LogMgr:ctor()
	self._count = 0;
	self._logList = {};
end
function LogMgr:printLog(tag,fmt, ...)
	local t = {"[",tostring(tag),"] ",string.format(tostring(fmt), ...)};
	local str = table.concat(t);
	if self._count == MAX_COUNT then
		table.remove(self._logList, 1)
		self._count = MAX_COUNT - 1
	end
	self._count = self._count + 1;
	self._logList[self._count] = str;
	print(str)
end

function LogMgr:getLogList()
	return self._logList;
end

function LogMgr:printDebug(fmt,...)
	if LOG_LEVEL.DEBUG then
		self:printLog("DEBUG",fmt,...);
	end
end

function LogMgr:printNotice(fmt,...)
    if LOG_LEVEL.NOTICE then
		self:printLog("NOTICE",fmt,...);
	end
end

function LogMgr:printWarn(fmt,...)
	if LOG_LEVEL.WARN then
		self:printLog("WARN",fmt,...);
	end
end

function LogMgr:printError(fmt,...)
	if LOG_LEVEL.ERROR then
		self:printLog("ERROR",fmt,...);
		print(debug.traceback("", 2))
	end
end

function LogMgr:printFatal(fmt,...)
	if LOG_LEVEL.FATAL then
		self:printLog("FATAL",fmt,...);
		print(debug.traceback("", 2))
	end
end

function LogMgr:printFuncCall(fmt,...)
    if LOG_LEVEL.FUNC then
        local endStr = string.split(debug.traceback("", 2),"\n")[3];
        local pathS = string.find(endStr,'%[');
        local pathE = string.find(endStr,']');
        local path = string.sub(endStr,pathS,pathE);
        path = string.sub(path,9,#path - 1);
        local fileName = io.pathinfo(path).basename;
        local index = string.find(endStr,"'");
        local funcName = "##########";
        if index then
            funcName = string.sub(endStr,string.find(endStr,"'") + 1,#endStr - 1);
        end
        self:printLog("FuncCall","%s:%s",fileName,funcName);
	end
end

function LogMgr:printDump(value, desciption, nesting)
    if LOG_LEVEL.DUMP then
        if type(nesting) ~= "number" then nesting = 3 end
        local lookupTable = {}
        local result = {}
        local function _v(v)
            if type(v) == "string" then
                v = "\"" .. v .. "\""
            end
            return tostring(v)
        end
        local traceback = string.split(debug.traceback("", 2), "\n")
        print("dump from: " .. string.trim(traceback[3]))
        local function _dump(value, desciption, indent, nest, keylen)
            desciption = desciption or "<var>"
            local spc = ""
            if type(keylen) == "number" then
                spc = string.rep(" ", keylen - string.len(_v(desciption)))
            end
            if type(value) ~= "table" then
                result[#result +1 ] = string.format("%s%s%s = %s", indent, _v(desciption), spc, _v(value))
            elseif lookupTable[value] then
                result[#result +1 ] = string.format("%s%s%s = *REF*", indent, desciption, spc)
            else
                lookupTable[value] = true
                if nest > nesting then
                    result[#result +1 ] = string.format("%s%s = *MAX NESTING*", indent, desciption)
                else
                    result[#result +1 ] = string.format("%s%s = {", indent, _v(desciption))
                    local indent2 = indent.."    "
                    local keys = {}
                    local keylen = 0
                    local values = {}
                    for k, v in pairs(value) do
                        keys[#keys + 1] = k
                        local vk = _v(k)
                        local vkl = string.len(vk)
                        if vkl > keylen then keylen = vkl end
                        values[k] = v
                    end
                    table.sort(keys, function(a, b)
                        if type(a) == "number" and type(b) == "number" then
                            return a < b
                        else
                            return tostring(a) < tostring(b)
                        end
                    end)
                    for i, k in ipairs(keys) do
                        _dump(values[k], k, indent2, nest + 1, keylen)
                    end
                    result[#result +1] = string.format("%s}", indent)
                end
            end
        end
        _dump(value, desciption, "- ", 1)

        for i, line in ipairs(result) do
            print(line)
        end
    end
end

mgrs.log = nil;
mgrs.singleClass(mgrs,LogMgr,"log");
